package models

import (
	"errors"
	"fmt"
	"strconv"

	"xorm.io/builder"
)

type Field struct {
	Id              int    `xorm:"not null pk autoincr comment('自增主键') INT(11)" form:"field_id"`
	SchoolId        int    `form:"school_id" xorm:"not null comment('驾校id外键关联dts_school中的id') index INT(11)"`
	FieldCode       string `xorm:"default '' comment('教学区域名称 训练场编号各驾校可按照自行规则制定') VARCHAR(4)" form:"field_code"`
	Address         string `xorm:"not null comment('训练场地址') VARCHAR(512)" form:"address"`
	Type            string `xorm:"not null default '1' comment('教学区域类型 1：第二部分；2：第三部分') ENUM('1','2','3','4')" form:"type"`
	TrainingCarType string `xorm:"not null comment('培训车型 下列编码可多选，以英文逗号分隔 A1,A2,A3,B1,B2,C1,C2,C3,C4,C5,D,E,F,M,N,P') VARCHAR(512)" form:"training_car_type"`
	Area            int    `xorm:"default 0 comment('训练场地面积') INT(11)" form:"area"`
	Description     string `xorm:"comment('训练场描述信息') VARCHAR(128)" form:"description"`
	ApprovalStatus  string `xorm:"default '0' comment('训练场地提交运管审核状态，0:待审核，1:通过审核，2:未通过审核') ENUM('0','1','2')" `
	RecordStatus    string `xorm:"not null default '0' comment('备案状态 0:未备案 1:已备案') ENUM('0','1')"`
	Totalvehnum     int    `xorm:"default 0 comment('可容纳车辆数') INT(11)" form:"totalvehnum"`
	Curvehnum       int    `xorm:"default 0 comment('已投放车辆数') INT(11)" form:"curvehnum"`
	Name            string `xorm:"comment('教学区域名称') VARCHAR(255)" form:"name"`
	Remark          string `xorm:"VARCHAR(255) default ''" `
	Isused          string `xorm:"default '1' comment('0 已删除  1未删除') ENUM('0','1')"`
	InstitutionCode string `xorm:"CHAR(16) default ''"`
	Reason          string `xorm:"CHAR(255) default ''"`
}

type FieldInfo struct {
	Id              int64  `json:"id"`
	FieldCode       string `json:"field_code"`
	Address         string `json:"address"`
	Area            string `json:"area"`
	Description     string `json:"description"`
	ApprovalStatus  string `json:"approval_status"`
	TrainingCarType string `json:"training_car_type"`
	Type            string `json:"type"`
	Totalvehnum     int    `json:"totalvehnum"`
	Curvehnum       int    `json:"curvehnum"`
	Name            string `json:"name"`
	Reason          string `json:"reason"`
	RecordStatus    string `json:"record_status"`
}

func (c *Field) CheckLastFieldCode(school_id string) (has bool, field Field, err error) {
	has, err = engine.Table("dts_field").Where("school_id = ?", school_id).Desc("field_code").Get(&field)
	return has, field, err
}

func (c *Field) GetField(school_id string, filter builder.Cond) (has bool, list Field, err error) {
	has, err = engine.Table("dts_field").Alias("f").
		Where("f.school_id=?", school_id).And(filter).Get(&list)
	return has, list, err
}

func (c *Field) GetFieldList(school_id string, pageSize, offset int) (list []*FieldInfo, err error) {
	sess := engine.Table("dts_field").Alias("f").
		Select("f.id,f.field_code,f.address,f.area,f.description,f.approval_status,f.training_car_type,f.type,f.totalvehnum,f.curvehnum,f.name,f.record_status,f.reason").
		Where("f.school_id=? and f.isused=?", school_id, "1").Desc("f.id").Limit(pageSize, offset)
	if err = sess.Find(&list); err != nil {
		return list, err
	}
	for k, _ := range list {
		if list[k].Area == "0" {
			list[k].Area = ""
		}
	}
	return list, nil
}

func (c *Field) GetClosurePoint(school_id, id string) (list []*ClosurePoint, err error) {
	sess := engine.Table("dts_field").Alias("f").
		Select("dcp.latitude,dcp.longitude,dcp.order,dcp.id,dcp.closure_id").Join("LEFT", []string{"dts_closure", "dc"}, "dc.field_id=f.id").
		Join("LEFT", []string{"dts_closure_point", "dcp"}, "dcp.closure_id=dc.id").
		Where("f.school_id=? and f.id=?", school_id, id).Asc("dcp.order")
	if err = sess.Find(&list); err != nil {
		fmt.Println(err.Error())
		return list, err
	}
	return list, err
}

type FieldList struct {
	Id       int       `json:"id"`
	Name     string    `json:"name"`
	Position []*Points `xorm:"-" json:"position"`
}

func (c *Field) GetClosurePoints(school_id int) (list []*FieldList, err error) {
	sess := engine.Table("dts_field").Alias("f").
		Select("dc.id,f.name").
		Join("LEFT", []string{"dts_closure", "dc"}, "dc.field_id=f.id").
		Where("f.school_id=? and f.isused = ? ", school_id, "1").Asc("f.id")
	if err = sess.Find(&list); err != nil {
		fmt.Println(err.Error())
		return list, err
	}
	return list, err
}

func (c *Field) GetFieldById(Id string) (list *Field, err error) {
	var (
		fieldid int
	)

	list = new(Field)
	if fieldid, err = strconv.Atoi(Id); err != nil {
		return list, err
	} else {
		if _, err = engine.Table("dts_field").Select("*").Where("id=? and isused=?", fieldid, "1").Get(list); err != nil {
			return list, err
		}
	}
	return list, err
}

func (c *Field) Save() (field *Field, err error) {
	c.RecordStatus = "0"   //备案状态 0：未备案   1：已备案
	c.ApprovalStatus = "0" //待审核
	c.Isused = "1"
	c.Remark = ""
	Field_code, _ := strconv.Atoi(c.FieldCode)
	Fieldcode := fmt.Sprintf("%04d", Field_code)
	c.FieldCode = Fieldcode
	if err = c.CheckByFieldCode(Fieldcode); err == nil {
		return nil, errors.New("该围栏编号已存在")
	}
	if err = c.CheckByFieldName(c.Name); err == nil {
		return nil, errors.New("该围栏名称已存在")
	}
	if c.Curvehnum > c.Totalvehnum {
		return nil, errors.New("投放车辆不应大于可容纳车辆数")
	}
	if c.Type == "" {
		return nil, errors.New("请选择教学区域类型")
	}
	if c.Name == "" {
		return nil, errors.New("请输入教学区域名称")
	}
	_, err = engine.Insert(c)
	return c, err
}

func (c *Field) Edit(field ...string) bool {
	var (
		err error
	)
	if c.ApprovalStatus == "1" {
		return false
	}
	_, err = engine.Id(c.Id).Cols(field...).Update(c)
	if err != nil {
		return false
	}
	return true
}

func (c *Field) Add() bool {
	if _, err := engine.Insert(c); err != nil {
		return false
	}
	return true
}

func (c *Field) DelById() bool {
	var (
		err error
	)
	if c.ApprovalStatus == "1" {
		return false
	}
	field := new(Field)
	field.Id = c.Id
	field.Isused = "0"
	field.Remark = c.InstitutionCode
	field.InstitutionCode = ""
	_, err = engine.Id(c.Id).Update(field)
	if err != nil {
		return false
	}
	return true
}

func (c *Field) CheckById(id string) (err error) {
	var temp int64
	if temp, err = strconv.ParseInt(id, 10, 64); err != nil {
		return err
	}
	if has, err := engine.Table("dts_field").Where("id=?", temp).Exist(); err == nil && has {
		//存在
		return nil
	} else {
		return errors.New("不存在")
	}
}

func (c *Field) CheckByFieldCode(code string) (err error) {
	if has, err := engine.Table("dts_field").Where("field_code=? and school_id=?", code, c.SchoolId).Exist(); err == nil && has {
		//存在
		return nil
	} else {
		return errors.New("不存在")
	}
}

func (c *Field) CheckByFieldName(name string) (err error) {
	if has, err := engine.Table("dts_field").Where("name=? and school_id=?", name, c.SchoolId).Exist(); err == nil && has {
		//存在
		return nil
	} else {
		return errors.New("不存在")
	}
}

func (c *Field) GetFieldByFilter(filter builder.Cond) (list *Field, err error) {

	list = new(Field)
	if _, err = engine.Table("dts_field").And(filter).Get(list); err != nil {
		return list, err
	}
	return list, err
}

func (c *Field) GetRecordMsgField(filter builder.Cond) (list *Field, err error) {

	list = new(Field)
	if _, err = engine.Table("dts_field").Alias("fd").
		Join("LEFT", []string{"dts_school", "sl"}, "fd.school_id = sl.id").
		And(filter).Get(list); err != nil {
		return list, err
	}
	return list, err
}

func (c *Field) GetOneFieldById(id int64) (list Field, err error) {
	_, err = engine.Table("dts_field").
		Where("id = ?", id).
		Get(&list)
	return list, err
}

func (c *Field) Update(field ...string) bool {
	var (
		err error
	)
	_, err = engine.Id(c.Id).Cols(field...).Update(c)
	if err != nil {
		return false
	}
	return true
}
